package dbsync

import (
	"fmt"
	"strings"
)

// 通用插入数据
func updateSqlite(
	db SQLCommon,
	tableName string,
	data []interface{},
	options UpdateOptions,
) (err error) {
	// 列名和索引的映射关系
	mapItem := make(map[string]int)
	for i, fieldName := range options.Columns {
		mapItem[fieldName] = i
	}
	i, columnsLen := 0, len(options.Columns)
	for k := range options.FixedFields {
		mapItem[k] = columnsLen + i
		i++
	}
	mapItemLen := len(mapItem)
	// 生成唯一键或主键的判断映射
	uniqueMap := make(map[string]bool)
	for _, k := range options.UniqueFields {
		uniqueMap[k] = true
	}
	// 生成时间列的判断映射
	timeMap := make(map[string]bool)
	for _, k := range options.TimeFields {
		timeMap[k] = true
	}
	// 生成SQL语句的列名、问号、值列表
	columns := make([]string, mapItemLen)
	updateColumns := make([]string, 0)
	updateKeyMap := make(map[string]int)
	questions := make([]string, mapItemLen)
	for k, num := range mapItem {
		columns[num] = k
		if uniqueMap[k] != true {
			updateKeyMap[k] = len(updateColumns)
			updateColumns = append(updateColumns, fmt.Sprintf("%s=?", k))
		}
		questions[num] = "?"
	}
	colStr, questionStr, updateStr := strings.Join(columns, ","), fmt.Sprintf("(%s)", strings.Join(questions, ",")), strings.Join(updateColumns, ",")
	values := make([]interface{}, mapItemLen+len(updateColumns))
	for fieldName, index := range mapItem {
		if index >= columnsLen {
			values[index] = options.FixedFields[fieldName]
		} else {
			if timeMap[fieldName] == true {
				values[index] = convertTimeType(data[index])
			} else {
				values[index] = data[index]
			}
		}
		if v, ok := updateKeyMap[fieldName]; ok {
			values[mapItemLen+v] = values[index]
		}
	}
	// 生成ON CONFLICT主键列表
	uniqueKeyStr := strings.Join(options.UniqueFields, ",")
	// 生成并执行SQL语句
	sqlStr := fmt.Sprintf("INSERT INTO %s (%s) VALUES %s ON CONFLICT(%s) DO UPDATE SET %s",
		tableName, colStr, questionStr, uniqueKeyStr, updateStr)
	_, err = db.Exec(sqlStr, values...)
	return
}
